﻿using Collector.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Collector.Factory
{
    class FactoryMain : GenericMold
    {
        private string TAG = "FactoryMain:";
        private bool mIsPrepared = false, mIsChecked = false;
        private ProductType mProductType = ProductType.ePRODUCT_TYPE_SINGLE;
        // 加压mmHg门限值的最小门限系数
        private double mThresholdRatio = 0;
        private string mSegmentTargetSet;

        public bool Prepared(double thresholdRatio, string targetList, ProductType type, bool check)
        {
            mIsPrepared = initialization();
            if (mIsPrepared && check)
            {
                mIsPrepared = checkAndPreparedDeviceInfo();
                if(!mIsPrepared)
                {
                    deinitialization();
                }
            }

            mThresholdRatio = thresholdRatio;
            mSegmentTargetSet = targetList;
            mProductType = type;

            return mIsPrepared;
        }

        public bool Check()
        {
            // Already checked
            if (mIsChecked)
                return true;

            mIsChecked = checkAndPreparedDeviceInfo();
            return mIsChecked;
        }

        public bool Start()
        {
            bool ret = false;
            if (!mIsPrepared && !mIsChecked)
            {
                Log.Error(TAG + "No check and prepare device info.");
                return false;
            }

            ConditionWait.Reset();
            if (mProductType == ProductType.ePRODUCT_TYPE_THREE)
            {
                ret = Threebodyparts_segmented();
            }
            else
            {
                ret = Single_segmented();
            }
            
            Log.Debug(TAG + "Start()");
            ConditionWait.Set();
            return ret;
        }

        public void Stop()
        {
            // 应该互斥，确保可重入
            if (mIsPrepared)
            {
                // 提前将状态 置为false. 避免函数重入
                mIsPrepared = false;
                mIsChecked = false;
                deinitialization();
                Log.Debug(TAG + "Stop()");
            }
        }

        public void Stop(Action giveback)
        {
            if (mIsPrepared)
            {
                Stop();
            }

            giveback();
        }

        public bool BurnDeviceSerialnumber(string newSN, out string reason)
        {
            return writeDeviceSerialnumber(newSN, out reason);
        }

        public bool GetDeviceSerialnumber(out string serialnumber)
        {
            return readDeviceSerialnumber(out serialnumber);
        }

        public bool BurnDeviceFixedFrequency(string newFrequency)
        {
            return DCManager.WriteDeviceFixedFre(newFrequency);
        }

        public bool GetDeviceFixedFrequency(out string frequency)
        {
            return DCManager.ReadDeviceFixedFre(out frequency);
        }

        public bool BurnDeviceAirCalibration()
        {
            return DCManager.AirpressureCalibration();
        }

        public bool GetAirpressureCalibration(out double pressureOfPeeling)
        {
            return DCManager.ReadAirPressureOfPeeling(out pressureOfPeeling);
        }

        private bool Threebodyparts_segmented()
        {
            PulseCommonHelper.Display display = new PulseCommonHelper.Display();

            // 将分段压力值转换成int
            List<int> mmHgListInfo = mSegmentTargetSet.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(Int32.Parse).ToList();

            // 创建三部基线压力
            Dictionary<BodyPart, double> baseLineMap = new Dictionary<BodyPart, double>
            {
                {BodyPart.eBODY_PART_CUN, Baselines[0]*100.0 },
                {BodyPart.eBODY_PART_GUAN, Baselines[1]*100.0 },
                {BodyPart.eBODY_PART_CHI, Baselines[2]*100.0 }
            };

            // 创建分段对象
            PulseThreeBodyPartsSegmentCollector PSProcessing = new PulseThreeBodyPartsSegmentCollector(baseLineMap, mmHgListInfo);
            SerialPort.SerialPort.collector = PSProcessing;
            PSProcessing.DeviceCommunication = DCManager;
            PSProcessing.notifyMainForm += new CollectorUINotifyHandler<PulseCommonHelper.Display>(CollectorUINotify);
            PSProcessing.ThresholdRadio = mThresholdRatio;
            PSProcessing.RawDataPath = null;

            // Write pulse data to file.
            PSProcessing.UserRightHandSel = false;
            PSProcessing.PhoneNumber = "00000000000";
            PSProcessing.SerialNumber = DeviceSerialNumber;

            bool ret = PSProcessing.DoSubsectionProcessing();
            if (ret)
            {
                display.Message = "分段加压测试 PASS";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return ret;
            }
            else
            {
                display.Message = "分段加压测试 Fail";
                display.LogLevel = LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return false;
            }
        }

        private bool Single_segmented()
        {
            PulseCommonHelper.Display display = new PulseCommonHelper.Display();
            // 将分段压力值转换成int
            List<int> mmHgListInfo = mSegmentTargetSet.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(Int32.Parse).ToList();


            // 创建分段对象
            PulseSingleSegmentCollector PSProcessing = new PulseSingleSegmentCollector(Baselines[0], mmHgListInfo);
            SerialPort.SerialPort.collector = PSProcessing;
            PSProcessing.DeviceCommunication = DCManager;
            PSProcessing.notifyMainForm += new CollectorUINotifyHandler<PulseCommonHelper.Display>(CollectorUINotify);
            PSProcessing.ThresholdRadio = mThresholdRatio;
            PSProcessing.RawDataPath = null;

            // 治具默认存储数据
            PSProcessing.UserRightHandSel = false;
            PSProcessing.PhoneNumber = "00000000000";
            PSProcessing.SerialNumber = DeviceSerialNumber;


            bool ret = PSProcessing.DoSubsectionProcessing();
            if (ret)
            {
                display.Message = "分段加压测试 PASS";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                return ret;
            }
            else
            {
                display.Message = "分段加压测试 Fail";
                display.LogLevel = LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();
                // 开始泄压
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return false;
            }
        }

        private int CollectorUINotify(PulseCommonHelper.Display obj, PulseCommonHelper.Display.DisplayType type)
        {
            notifyMessage(obj, type);
            return 0;
        }
    }
}
